package com.ssm.juc.quque;

import org.jetbrains.annotations.NotNull;

import java.util.concurrent.*;

/**
 * 延迟队列
 *
 * @author zhengsh
 */
public class DelayQueueTest {


    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<DelayObject> delayQueue = new DelayQueue<>();

        System.out.println("MH737 登机通道 ---> 开始排队");

        // 第二步，延迟对象/参数入队，以及传入延迟时间
        delayQueue.put(new DelayObject("VIP0 张三", 3000L));
        System.out.println("VIP0 张三进入排队队列");
        delayQueue.put(new DelayObject("VIP0 李四", 3000L));
        System.out.println("VIP0 李四进入排队队列");
        delayQueue.put(new DelayObject("VIP1 王五", 2000L));
        System.out.println("VIP1 王五进入排队队列");
        delayQueue.put(new DelayObject("VIP2 赵六", 1000L));
        System.out.println("VIP2 赵六进入排队队列");

        // 第三步，到期执行
        for (; ; ) {
            DelayObject delayObj = delayQueue.poll(5000, TimeUnit.MILLISECONDS);
            if (delayObj == null) {
                break;
            }
            System.out.println("欢迎光临," + delayObj.name + "登机就坐");
        }

        System.out.println("MH737 登机通道 ---> 登机完成");
        System.out.println("MH737 关闭舱门 ---> 准备起飞");
    }

    /**
     * 第一步：实现 Delayed 接口的 getDelay 方法
     */
    static class DelayObject implements Delayed {

        private String name;
        private Long time;

        public DelayObject(String name, Long delayTime) {
            this.name = name;
            this.time = System.currentTimeMillis() + delayTime;
        }


        @Override
        public long getDelay(@NotNull TimeUnit unit) {
            long diff = time - System.currentTimeMillis();
            return unit.convert(diff, TimeUnit.MILLISECONDS);
        }

        @Override
        public int compareTo(@NotNull Delayed obj) {
            if (this.time < ((DelayObject) obj).getTime()) {
                return -1;
            }
            if (this.time > ((DelayObject) obj).getTime()) {
                return 1;
            }
            return 0;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Long getTime() {
            return time;
        }

        public void setTime(Long time) {
            this.time = time;
        }
    }
}
